//
//  NSString+Extensions.m
//  YJFinancial
//
//  Created by David Qu on 14-6-2.
//  Copyright (c) 2014年 David Qu Studio. All rights reserved.
//

#import "NSString+Extensions.h"


@implementation NSString (Extensions)

+ (NSString *)stringFromDate:(NSDate *)date format:(NSString *)strFormat
{
    NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
    
    [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];
    
    [dateFormatter setDateFormat:strFormat];
    
    NSString *dateString = [dateFormatter stringFromDate:date];

    return dateString;
}

+ (NSDate *)dateFromString:(NSString *)strDate format:(NSString *)strFormat
{
    NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
    
    [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];
    
    [dateFormatter setDateFormat:strFormat];
    
    NSDate *date = [dateFormatter dateFromString:strDate];
    
    return date;
}

#pragma mark - 转换string大小写

- (NSString *)lowercaseFirstCharacter {
    NSRange range = NSMakeRange(0,1);
    NSString *lowerFirstCharacter = [[self substringToIndex:1] lowercaseString];
    return [self stringByReplacingCharactersInRange:range withString:lowerFirstCharacter];
}

- (NSString *)uppercaseFirstCharacter {
    NSRange range = NSMakeRange(0,1);
    NSString *upperFirstCharacter = [[self substringToIndex:1] uppercaseString];
    return [self stringByReplacingCharactersInRange:range withString:upperFirstCharacter];
}

#pragma mark - trim string

- (NSString *)trim {
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSString *)trimTheExtraSpaces{
    NSCharacterSet *whitespaces = [NSCharacterSet whitespaceCharacterSet];
    NSPredicate *noEmptyStrings = [NSPredicate predicateWithFormat:@"SELF != ''"];
    
    NSArray *parts = [self componentsSeparatedByCharactersInSet:whitespaces];
    NSArray *filteredArray = [parts filteredArrayUsingPredicate:noEmptyStrings];
    return [filteredArray componentsJoinedByString:@" "];
}

//是否是空字符串
//- (BOOL)isEmpty {
//    NSCharacterSet *charSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
//    NSString *trimmed = [self stringByTrimmingCharactersInSet:charSet];
//    return [trimmed isEqualToString:@""];
//}

+ (BOOL)isStringEmpty:(NSString *)string {
    if([string length] == 0) {
        //string is empty or nil
        return YES;
    }
    
    if(![[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]) {
        //string is all whitespace
        return YES;
    }
    
    return NO;
}

+ (BOOL)isStringEmpty2:(NSString *)string
{
    if([string length] == 0) {
        //string is empty or nil
        return YES;
    }
    
    if (string == nil
        ||string == NULL
        ||[string isEqualToString:@"null"]
        ||[string isEqualToString:@"NULL"]
        ||[string isEqualToString:@""]
        ||[string isEqualToString:@"(null)"] ) {
        return YES;
    }
    
    if(![[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]) {
        //string is all whitespace
        return YES;
    }
    
    return NO;
}

- (BOOL)isEmptyString {
    if([self length] == 0) {
        //string is empty or nil
        return YES;
    }
    
    if (self == nil) {
        return YES;
    }
    
    if(![[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]) {
        //string is all whitespace
        return YES;
    }
    
    return NO;
}

//替换HTML代码
- (NSString *)escapeHTML {
    NSMutableString *result = [[NSMutableString alloc] initWithString:self];
    [result replaceOccurrencesOfString:@"&" withString:@"&amp;" options:NSLiteralSearch range:NSMakeRange(0, [result length])];
    [result replaceOccurrencesOfString:@"<" withString:@"&lt;" options:NSLiteralSearch range:NSMakeRange(0, [result length])];
    [result replaceOccurrencesOfString:@">" withString:@"&gt;" options:NSLiteralSearch range:NSMakeRange(0, [result length])];
    [result replaceOccurrencesOfString:@"\"" withString:@"&quot;" options:NSLiteralSearch range:NSMakeRange(0, [result length])];
    [result replaceOccurrencesOfString:@"'" withString:@"&#39;" options:NSLiteralSearch range:NSMakeRange(0, [result length])];
    return result;
}

// implementation by Daniel Dickison and Walty
// http://stackoverflow.com/questions/1105169/html-character-decoding-in-objective-c-cocoa-touch
- (NSString *)stringByDecodingXMLEntities {
    NSUInteger myLength = [self length];
    NSUInteger ampIndex = [self rangeOfString:@"&" options:NSLiteralSearch].location;
    
    // Short-circuit if there are no ampersands.
    if (ampIndex == NSNotFound) {
        return self;
    }
    // Make result string with some extra capacity.
    NSMutableString *result = [NSMutableString stringWithCapacity:(myLength * 1.25)];
    
    // First iteration doesn't need to scan to & since we did that already, but for code simplicity's sake we'll do it again with the scanner.
    NSScanner *scanner = [NSScanner scannerWithString:self];
    [scanner setCharactersToBeSkipped:nil];
    
    NSCharacterSet *boundaryCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@" \t\n\r;"];
    
    do {
        // Scan up to the next entity or the end of the string.
        NSString *nonEntityString;
        if ([scanner scanUpToString:@"&" intoString:&nonEntityString]) {
            [result appendString:nonEntityString];
        }
        if ([scanner isAtEnd]) {
            goto finish;
        }
        // Scan either a HTML or numeric character entity reference.
        if ([scanner scanString:@"&amp;" intoString:NULL])
            [result appendString:@"&"];
        else if ([scanner scanString:@"&apos;" intoString:NULL])
            [result appendString:@"'"];
        else if ([scanner scanString:@"&quot;" intoString:NULL])
            [result appendString:@"\""];
        else if ([scanner scanString:@"&lt;" intoString:NULL])
            [result appendString:@"<"];
        else if ([scanner scanString:@"&gt;" intoString:NULL])
            [result appendString:@">"];
        else if ([scanner scanString:@"&#" intoString:NULL]) {
            BOOL gotNumber;
            unsigned charCode;
            NSString *xForHex = @"";
            
            // Is it hex or decimal?
            if ([scanner scanString:@"x" intoString:&xForHex]) {
                gotNumber = [scanner scanHexInt:&charCode];
            }
            else {
                gotNumber = [scanner scanInt:(int*)&charCode];
            }
            
            if (gotNumber) {
                [result appendFormat:@"%C", charCode];
                [scanner scanString:@";" intoString:NULL];
            }
            else {
                NSString *unknownEntity = @"";
                [scanner scanUpToCharactersFromSet:boundaryCharacterSet intoString:&unknownEntity];
                [result appendFormat:@"&#%@%@", xForHex, unknownEntity];
                NSLog(@"Expected numeric character entity but got &#%@%@;", xForHex, unknownEntity);
            }
        }
        else {
            NSString *amp;
            [scanner scanString:@"&" intoString:&amp];      //an isolated & symbol
            [result appendString:amp];
        }
    }
    while (![scanner isAtEnd]);
    
finish:
    return result;
}

//普通的MD5加密
- (NSString *)md5 {
    const char *cStr = [self UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cStr, strlen(cStr), result);
    return [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]];
}

//UTF16的MD5加密
- (NSString *)md5ForUTF16{
    NSData *temp = [self dataUsingEncoding:NSUTF16LittleEndianStringEncoding];
    
    UInt8 *cStr = (UInt8 *)[temp bytes];
    
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cStr, [temp length], result);
    return [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15]];
}

//自适应文字大小
- (CGFloat)fontSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size {
    CGFloat fontSize = [font pointSize];
    CGFloat height = 0;
    if (IOS_VERSION < 6) {
        height = [self sizeWithFont:font constrainedToSize:CGSizeMake(size.width,FLT_MAX) lineBreakMode:UILineBreakModeWordWrap].height;
    } else {
        height = [self sizeWithFont:font constrainedToSize:CGSizeMake(size.width,FLT_MAX) lineBreakMode:NSLineBreakByWordWrapping].height;
    }
    
    UIFont *newFont = font;
    
    //Reduce font size while too large, break if no height (empty string)
    while (height > size.height && height != 0) {
        fontSize--;
        newFont = [UIFont fontWithName:font.fontName size:fontSize];
        if (IOS_VERSION < 6) {
            height = [self sizeWithFont:newFont constrainedToSize:CGSizeMake(size.width,FLT_MAX) lineBreakMode:UILineBreakModeWordWrap].height;
        } else {
            height = [self sizeWithFont:newFont constrainedToSize:CGSizeMake(size.width,FLT_MAX) lineBreakMode:NSLineBreakByWordWrapping].height;
        }
        
    };
    
    // Loop through words in string and resize to fit
    //    for (NSString *word in [self componentsSeparatedByString:@" "]) {
    //        CGFloat width = [word sizeWithFont:newFont].width;
    //        while (width > size.width && width != 0) {
    //            fontSize--;
    //            newFont = [UIFont fontWithName:font.fontName size:fontSize];
    //            width = [word sizeWithFont:newFont].width;
    //        }
    //    }
    return fontSize;
}

#pragma mark - tokeniztion string

/**
 根据设定参数进行字符串拆分
 NSStringEnumerationByComposedCharacterSequences,根据字母
 NSStringEnumerationByWords，根据单词
 NSStringEnumerationBySentences，根据句子
 这3个比较常用
 */
- (NSMutableArray *)tokenizationStringByNSStringEnumerationOptions:(NSStringEnumerationOptions)opts{
    NSMutableArray *splitArray = [NSMutableArray array];
    NSRange range = NSMakeRange(0, [self length]);
    [self enumerateSubstringsInRange:range options:opts usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
        [splitArray addObject:substring];
    }];
    
    return splitArray;
}

//detect string language，对于句子相对准确，单词不是很准确
- (NSString *)languageForString{
    return (__bridge NSString *)CFStringTokenizerCopyBestStringLanguage((CFStringRef)self, CFRangeMake(0, MIN(self.length,400)));
}

//分析句中单词的词性
- (NSMutableArray *)analyseTextOfSentences{
    NSMutableArray *analyseArray = [NSMutableArray array];
    
    // This range contains the entire string, since we want to parse it completely
    NSRange stringRange = NSMakeRange(0, self.length);
    
    //第一种方式
    NSLinguisticTagger *tagger = [[NSLinguisticTagger alloc] initWithTagSchemes:[NSArray arrayWithObject:NSLinguisticTagSchemeNameTypeOrLexicalClass] options:0];
    [tagger setString:self];
    [tagger enumerateTagsInRange:stringRange
                          scheme:NSLinguisticTagSchemeNameTypeOrLexicalClass
                         options:NSLinguisticTaggerOmitWhitespace | NSLinguisticTaggerOmitPunctuation
                      usingBlock:^(NSString *tag, NSRange tokenRange, NSRange sentenceRange, BOOL *stop) {
                          [analyseArray addObject:@{@"word":[self substringWithRange:tokenRange],@"tag" : tag}];
                      }];
    
    // 第二种方式
    //    NSArray *language = [NSArray arrayWithObjects:@"en",@"de",@"fr",@"ko",@"ja",nil];
    //    NSDictionary* languageMap = [NSDictionary dictionaryWithObject:language forKey:@"Latn"];
    //
    //    [self enumerateLinguisticTagsInRange:stringRange
    //                                  scheme:NSLinguisticTagSchemeNameTypeOrLexicalClass
    //                                 options:NSLinguisticTaggerOmitWhitespace | NSLinguisticTaggerOmitPunctuation
    //                             orthography:[NSOrthography orthographyWithDominantScript:@"Latn" languageMap:languageMap]
    //                              usingBlock:^(NSString *tag, NSRange tokenRange, NSRange sentenceRange, BOOL *stop) {
    //                                  [analyseArray addObject:@{@"word":[self substringWithRange:tokenRange],@"tag" : tag}];
    //                            }];
    
    return analyseArray;
}

- (NSString *)stringWithCapitalizedFirstCharacter
{
    if([self length] > 0) {
        NSString *firstChar = [self substringToIndex:1];
        firstChar = [firstChar uppercaseString];
        
        NSString *remainder = [self substringFromIndex:1];
        
        return [firstChar stringByAppendingString:remainder];
    }
    
    return self;
}

- (BOOL)isMobileNumberClassification
{
    /**
     * 手机号码
     * 移动：134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188,1705
     * 联通：130,131,132,152,155,156,185,186,1709
     * 电信：133,1349,153,180,189,1700
     */
    //    NSString * MOBILE = @"^1((3//d|5[0-35-9]|8[025-9])//d|70[059])\\d{7}$";//总况
    
    /**
     * 中国移动：China Mobile
     * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188，1705
     */
    NSString * CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d|705)\\d{7}$";
    /**
     * 中国联通：China Unicom
     * 130,131,132,152,155,156,185,186,1709
     */
    NSString * CU = @"^1((3[0-2]|5[256]|8[56])\\d|709)\\d{7}$";
    /**
     * 中国电信：China Telecom
     * 133,1349,153,180,189,1700
     */
    NSString * CT = @"^1((33|53|8[09])\\d|349|700)\\d{7}$";
    
    /**
     *  "[1]"代表第1位为数字1，"[34578]"代表第二位可以为3、4、5、7、8中的一个，"\\d{9}"代表后面是可以是0～9的数字，有9位。
     */
    NSString *telRegex = @"[1][34578]\\d{9}";//
    
    /**
     * 大陆地区固话及小灵通
     * 区号：010,020,021,022,023,024,025,027,028,029
     * 号码：七位或八位
     */
//    NSString * PHS = @"^0(10|2[0-5789]|\\d{3})\\d{7,8}$";
    
    
    //    NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
    NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM];
    NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU];
    NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT];
//    NSPredicate *regextestphs = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",PHS];
    
    NSPredicate *regextestctTel = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", telRegex];
    
    if (([regextestcm evaluateWithObject:self] == YES)
        || ([regextestct evaluateWithObject:self] == YES)
        || ([regextestcu evaluateWithObject:self] == YES)
        || ([regextestctTel evaluateWithObject:self] == YES)
        )
    {
        return YES;
    }
    else
    {
        return NO;
    }
}

- (BOOL)isValidateEmail
{
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    return [emailTest evaluateWithObject:self];
}

- (BOOL)isValidateUrl
{
    NSString *emailRegex = @"(http://|https://){1}[\\w\\.\\-/:]+";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    return [emailTest evaluateWithObject:self];
}

// 将JSON串转化为字典或者数组
- (id)vg_toArrayOrNSDictionary:(NSData *)jsonData
{
    NSError *error = nil;
    id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData
                                                    options:NSJSONReadingAllowFragments
                                                      error:&error];
    
    if (jsonObject != nil && error == nil){
        return jsonObject;
    }else{
        // 解析错误
        return nil;
    }
    
}

- (id)vg_JSONValue
{
    NSData* data = [self dataUsingEncoding:NSUTF8StringEncoding];
    __autoreleasing NSError* error = nil;
    id result = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
    if (error != nil) return nil;
    return result;
}

/**
 *  URLEncode
 */
- (NSString *)vg_URLEncodedString
{
    // CharactersToBeEscaped = @":/?&=;+!@#$()~',*";
    // CharactersToLeaveUnescaped = @"[].";
    
    NSString *unencodedString = self;
    NSString *encodedString = (NSString *)
    CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                              (CFStringRef)unencodedString,
                                                              NULL,
                                                              (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                              kCFStringEncodingUTF8));
    
    return encodedString;
}

/**
 *  URLDecode
 */
-(NSString *)vg_URLDecodedString
{
    //NSString *decodedString = [encodedString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding ];
    
    NSString *encodedString = self;
    NSString *decodedString  = ( NSString *)CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL,
                                                                                                                      (__bridge CFStringRef)encodedString,
                                                                                                                      CFSTR(""),
                                                                                                                      CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)));
    return decodedString;
}

- (BOOL)isPureInt:(NSString*)string
{
    NSScanner* scan = [NSScanner scannerWithString:string];
    int val;
    return[scan scanInt:&val] && [scan isAtEnd];
}

//判断是否为浮点形：
- (BOOL)isPureFloat:(NSString*)string
{
    NSScanner* scan = [NSScanner scannerWithString:string];
    float val;
    return[scan scanFloat:&val] && [scan isAtEnd];
}

+ (NSString *)getPriceString:(NSString *)str
{
    if ([NSString isStringEmpty:str]) {
        return @"0";
    }
    
    if ([str isPureFloat:str]) {
        str = [NSString stringWithFormat:@"%1.2f", str.doubleValue];
//        str = [NSString getVal:2 val:str.floatValue];
        
        if ([str containsString:@".00"]) {
            str = [NSString stringWithFormat:@"%ld", (long)str.integerValue];
        }
    } else if ([str isPureInt:str]) {
        str = [NSString stringWithFormat:@"%ld", (long)str.integerValue];
    }
    
    return str;
}

+ (NSString *)getVal:(int)decimalNum val:(float)fval
{
    float doubleNumber = fval;
    NSNumber *n = [NSNumber numberWithFloat:doubleNumber];
    NSNumberFormatter *nFormat = [[NSNumberFormatter alloc] init];
    [nFormat setNumberStyle:NSNumberFormatterNoStyle];
    [nFormat setMaximumFractionDigits:decimalNum];
    [nFormat setRoundingMode:NSNumberFormatterRoundHalfEven];
    [nFormat setRoundingIncrement:[NSNumber numberWithDouble:0.0001]];
    NSString *res = [nFormat stringFromNumber:n];
    NSLog(@"getVal -> %@", res);
    return res;
}

+ (NSString *)getMoney2:(float)number
{
    float dis = 1;
    NSDecimalNumberHandler* roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundUp scale:2 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];
    
    NSDecimalNumber *ouncesDecimal;
    
    NSDecimalNumber *twoDecimal;
    
    NSDecimalNumber *roundedOunces;
    
    ouncesDecimal = [[NSDecimalNumber alloc] initWithFloat:number];
    
    twoDecimal = [[NSDecimalNumber alloc] initWithFloat:dis];
    
    NSDecimal p = ouncesDecimal.decimalValue;
    NSDecimal d = twoDecimal.decimalValue;
    
    NSDecimal accumulator;
    
    NSDecimalMultiply(&accumulator, &p, &d, NSRoundUp);
    
    NSDecimalNumber *pd = [[NSDecimalNumber alloc] initWithDecimal:accumulator];
    
    NSString *str = [NSString getVal:3 val:pd.floatValue];
    NSLog(@"a---->%@", str);
    pd = [[NSDecimalNumber alloc] initWithString:str];
    NSLog(@"b---->%@", pd.stringValue);
    roundedOunces = [pd decimalNumberByRoundingAccordingToBehavior:roundingBehavior];
    
    return roundedOunces.stringValue;
}

+ (NSString *)getMoney3:(NSString *)dn
{
    NSDecimalNumberHandler* roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundUp scale:2 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];
    
    NSDecimalNumber *ouncesDecimal;
    
    NSDecimalNumber *twoDecimal;
    
    NSDecimalNumber *roundedOunces;
    
    ouncesDecimal = [NSDecimalNumber decimalNumberWithString:dn];
    
    twoDecimal = [[NSDecimalNumber alloc] initWithString:@"1"];
    
    NSDecimal p = ouncesDecimal.decimalValue;
    NSDecimal d = twoDecimal.decimalValue;
    
    NSDecimal accumulator;
    
    NSDecimalMultiply(&accumulator, &p, &d, NSRoundUp);
    
    NSDecimalNumber *pd = [[NSDecimalNumber alloc] initWithDecimal:accumulator];
    
    NSString *str = [NSString getVal:3 val:pd.floatValue];
    NSLog(@"get Money a ---->%@", str);
    pd = [[NSDecimalNumber alloc] initWithString:str];
    NSLog(@"get Money b ---->%@", pd.stringValue);
    
    roundedOunces = [pd decimalNumberByRoundingAccordingToBehavior:roundingBehavior];
    
    NSLog(@"get Money   ---->%@", roundedOunces.stringValue);
    
    return roundedOunces.stringValue;
}

- (BOOL)isOlderVersionThan2:(NSString*)otherVersion
{
    return ([self compare:otherVersion options:NSNumericSearch] == NSOrderedAscending);
}

- (BOOL)isNewerVersionThan2:(NSString*)otherVersion
{
    return ([self compare:otherVersion options:NSNumericSearch] == NSOrderedDescending);
}


#pragma mark 正则表达式／判断第一个是否以中文开头的方法
- (BOOL)pipeizimu:(NSString *)str
{
    //判断是否以字母开头
    NSString *ZIMU = @"/^[a-zA-z]/";
    NSPredicate *regextestA = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", ZIMU];
    
    if ([regextestA evaluateWithObject:str] == YES)
    {
        return YES;
    }
    else
    {
        return NO;
    }
}

+ (BOOL)isZhongWenFirst:(NSString *)firstStr
{
    //是否以中文开头(unicode中文编码范围是0x4e00~0x9fa5)
    int utfCode = 0;
    void *buffer = &utfCode;
    NSRange range = NSMakeRange(0, 1);
    //判断是不是中文开头的,buffer->获取字符的字节数据 maxLength->buffer的最大长度 usedLength->实际写入的长度，不需要的话可以传递NULL encoding->字符编码常数，不同编码方式转换后的字节长是不一样的，这里我用了UTF16 Little-Endian，maxLength为2字节，如果使用Unicode，则需要4字节 options->编码转换的选项，有两个值，分别是NSStringEncodingConversionAllowLossy和NSStringEncodingConversionExternalRepresentation range->获取的字符串中的字符范围,这里设置的第一个字符 remainingRange->建议获取的范围，可以传递NULL
    BOOL b = [firstStr getBytes:buffer maxLength:2 usedLength:NULL encoding:NSUTF16LittleEndianStringEncoding options:NSStringEncodingConversionExternalRepresentation range:range remainingRange:NULL];
    if (b && (utfCode >= 0x4e00 && utfCode <= 0x9fa5))
        return YES;
    else
        return NO;
}

- (BOOL)isEmoji {
    const unichar high = [self characterAtIndex: 0];
    
    // Surrogate pair (U+1D000-1F77F)
    if (0xd800 <= high && high <= 0xdbff) {
        const unichar low = [self characterAtIndex: 1];
        const int codepoint = ((high - 0xd800) * 0x400) + (low - 0xdc00) + 0x10000;
        
        return (0x1d000 <= codepoint && codepoint <= 0x1f77f);
        
        // Not surrogate pair (U+2100-27BF)
    } else {
        return (0x2100 <= high && high <= 0x27bf);
    }
}

- (BOOL)isIncludingEmoji {
    BOOL __block result = NO;
    
    [self enumerateSubstringsInRange:NSMakeRange(0, [self length])
                             options:NSStringEnumerationByComposedCharacterSequences
                          usingBlock: ^(NSString* substring, NSRange substringRange, NSRange enclosingRange, BOOL* stop) {
                              if ([substring isEmoji]) {
                                  *stop = YES;
                                  result = YES;
                              }
                          }];
    
    return result;
}

- (instancetype)removedEmojiString {
    NSMutableString* __block buffer = [NSMutableString stringWithCapacity:[self length]];
    
    [self enumerateSubstringsInRange:NSMakeRange(0, [self length])
                             options:NSStringEnumerationByComposedCharacterSequences
                          usingBlock: ^(NSString* substring, NSRange substringRange, NSRange enclosingRange, BOOL* stop) {
                              [buffer appendString:([substring isEmoji])? @"": substring];
                          }];
    
    return buffer;
}

//判断字符是否有字母或数字组成
+ (BOOL)isEnglishOrNumbers:(NSString *)string {
    //数字条件
    NSRegularExpression *tNumRegularExpression = [NSRegularExpression regularExpressionWithPattern:@"[0-9]" options:NSRegularExpressionCaseInsensitive error:nil];
    
    //符合数字条件的有几个字节
    NSUInteger tNumMatchCount = [tNumRegularExpression numberOfMatchesInString:string
                                                                       options:NSMatchingReportProgress
                                                                         range:NSMakeRange(0, string.length)];
    
    //英文字条件
    NSRegularExpression *tLetterRegularExpression = [NSRegularExpression regularExpressionWithPattern:@"[A-Za-z]" options:NSRegularExpressionCaseInsensitive error:nil];
    
    //符合英文字条件的有几个字节
    NSUInteger tLetterMatchCount = [tLetterRegularExpression numberOfMatchesInString:string options:NSMatchingReportProgress range:NSMakeRange(0, string.length)];
    
    if (tNumMatchCount == string.length) {
        //全部符合数字，表示沒有英文
        return YES;
    } else if (tLetterMatchCount == string.length) {
        //全部符合英文，表示沒有数字
        return YES;
    } else if (tNumMatchCount + tLetterMatchCount == string.length) {
        //符合英文和符合数字条件的相加等于密码长度
        return YES;
    } else {
        return NO;
        //可能包含标点符号的情況，或是包含非英文的文字，这里再依照需求详细判断想呈现的错误
    }
}

@end

